// vbe.h

/*
   Copyright 2007 Corey Tabaka

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#ifndef __VBE_H__
#define __VBE_H__

#include <ktypes.h>

#ifdef __GNUC__
#define PACKED __attribute__ ((packed))
#else
#define PACKED
#endif

enum {
	VBE_SUCCESS=0,
	VBE_FAILED=1,
	VBE_UNSUPPORTED=2,
	VBE_INVALID=3,
};

enum {
	VBE_CONTROLLER_INFO=0,
	VBE_MODE_INFO,
	VBE_SET_MODE,
	VBE_GET_MODE,
	VBE_DISPLAY_START=7,
	VBE_DDC_EXT=0x15,
};

typedef struct {
	uint8 vbeSignature[4];
	union {
		uint16 vbeVersion;
		struct {
			uint8 vbeVersionMinor;
			uint8 vbeVersionMajor;
		};
	};
	uint32 oemStringIdx;
	uint32 capabilities;
	uint32 videoModeIdx;
	uint16 totalMemory;
	
	uint16 oemSoftwareRev;
	uint32 oemVendorNameIdx;
	uint32 oemProductNameIdx;
	uint32 oemProductRevIdx;
	
	uint16 modes[111];
	
	char oemData[256];
} PACKED vbe_controller_info_t;

typedef struct {
	// all VBE versions
	uint16 modeAttributes;
	uint8 winAAttributes;
	uint8 winBAttributes;
	uint16 winGranularity;
	uint16 winSize;
	uint16 winASegment;
	uint16 winBSegment;
	uint32 winFuncPointer;
	uint16 bytesPerScanLine;
	
	// VBE 1.2
	uint16 xResolution;
	uint16 yResolution;
	uint8 xCharSize;
	uint8 yCharSize;
	uint8 numPlanes;
	uint8 bitsPerPixel;
	uint8 numBanks;
	uint8 memoryModel;
	uint8 bankSize;
	uint8 numImagePages;
	uint8 reserved_0;
	
	// Direct color fields (required for direct/6 and YUV/7 memory models)
	uint8 redMaskSize;
	uint8 redFieldPos;
	uint8 greenMaskSize;
	uint8 greenFieldPos;
	uint8 blueMaskSize;
	uint8 blueFieldPos;
	uint8 rsvdMaskSize;
	uint8 rsvdFieldPos;
	uint8 directColorModeInfo;
	
	// VBE 2.0
	uint32 physicalBase;
	uint32 reserved_1;
	uint16 reserved_2;
	
	// VBE 3.0
	uint16 linearBytesPerScanLine;
	uint8 numBankedImagePages;
	uint8 numLinearImagePages;
	uint8 linearRedMaskSize;
	uint8 linearRedFieldPos;
	uint8 linearGreenMaskSize;
	uint8 linearGreenFieldPos;
	uint8 linearBlueMaskSize;
	uint8 linearBlueFieldPos;
	uint8 linearRsvdMaskSize;
	uint8 linearRsvdFieldPos;
	uint32 maxPixelClock;
	
	uint8 reserved_3[189];
} PACKED vbe_modeinfo_t;

// mode attributes
enum {
	VBE_MODE_ATTR_HW_SUPPORT	= 0x0001,
	VBE_MODE_ATTR_BIOS_TTY_OUT	= 0x0004,
	VBE_MODE_ATTR_COLOR			= 0x0008,
	VBE_MODE_ATTR_GRAPHIC		= 0x0010,
	VBE_MODE_ATTR_NOT_VGA		= 0x0020,
	VBE_MODE_ATTR_NO_VGA_WINDOW	= 0x0040,
	VBE_MODE_ATTR_LINEAR_FB		= 0x0080,
	VBE_MODE_ATTR_DOUBLE_SCAN	= 0x0100,
	VBE_MODE_ATTR_INTERLACED	= 0x0200,
	VBE_MODE_ATTR_HW_TRIPLE_BUF	= 0x0400,
	VBE_MODE_ATTR_HW_STEREO		= 0x0800,
	VBE_MODE_ATTR_DUAL_DISP_SA	= 0x1000,
};

// window attributes
enum {
	VBE_WIN_ATTR_RELOCATABLE	= 0x01,
	VBE_WIN_ATTR_READABLE		= 0x02,
	VBE_WIN_ATTR_WRITABLE		= 0x04,
};

// memory model
enum {
	VBE_MEM_MODEL_TEXT			= 0x00,
	VBE_MEM_MODEL_CGA_GFX		= 0x01,
	VBE_MEM_MODEL_HERCULES_GFX	= 0x02,
	VBE_MEM_MODEL_PLANAR		= 0x03,
	VBE_MEM_MODEL_PACKED_PIXEL	= 0x04,
	VBE_MEM_MODEL_256_COLOR		= 0x05,
	VBE_MEM_MODEL_DIRECT_COLOR	= 0x06,
	VBE_MEM_MODEL_YUV			= 0x07,
};

// direct color mode info
enum {
	VBE_DIRECT_COLOR_PROG_COLOR_MAP	= 0x01,
	VBE_DIRECT_COLOR_RSVD_USEABLE	= 0x02,
};

typedef struct {
	uint16 horizontalTotal;
	uint16 horizontalSyncStart;
	uint16 horizontalSyncEnd;
	uint16 verticalTotal;
	uint16 verticalSyncStart;
	uint16 verticalSyncEnd;
	uint8 flags;
	uint32 pixelClock;
	uint16 refreshRate;
	
	uint8 reserved[40];
} PACKED vbe_crtc_info_t;

// CRTC flags
enum {
	VBE_CRTC_FLAGS_DOUBLE_SCAN	= 0x01,
	VBE_CRTC_FLAGS_INTERLACED	= 0x02,
	VBE_CRTC_FLAGS_HSYNC_NEG	= 0x04,
	VBE_CRTC_FLAGS_VSYNC_NEG	= 0x08,
};

typedef struct {
	uint16 mode			: 9;
	uint16 reserved_0	: 2;
	uint16 useCRTC		: 1;
	uint16 reserved_1	: 2;
	uint16 linear		: 1;
	uint16 noClear		: 1;
	
	vbe_crtc_info_t crtc;
} PACKED vbe_set_mode_t;

typedef struct {
	uint16 mode			: 14;
	uint16 linear		: 1;
	uint16 notCleared	: 1;
} PACKED vbe_get_mode_t;

typedef struct {
	uint8 function;
	union {
		uint32 displayStart;
		uint16 firstPixel;
	};
	union {
		uint32 rightImageStart;
		uint16 firstScanLine;
	};
} PACKED vbe_set_display_start_t;

enum {
	VBE_DISP_START_SET				= 0x00,
	VBE_DISP_START_GET				= 0x01,
	VBE_DISP_START_SCHEDULE			= 0x02,
	VBE_DISP_START_SCHEDULE_STEREO	= 0x03,
	VBE_DISP_START_GET_STATUS		= 0x04,
	VBE_DISP_START_ENABLE_STEREO	= 0x05,
	VBE_DISP_START_DISABLE_STEREO	= 0x06,
	VBE_DISP_START_SET_AT_VRETRACE	= 0x80,
	VBE_DISP_START_SET_AT_VRETRACE2	= 0x82,
	VBE_DISP_START_SET_STEREO_AT_VR	= 0x83,
};

typedef struct {
	uint8 reserved;
	union {
		uint16 firstPixel;
		bool flipped;
	};
	uint16 firstScanLine;
} PACKED vbe_get_display_start_t;

typedef struct {
	uint8 function;
	uint16 controller;
	uint16 blockNum;
} PACKED vbe_ddc_ext_t;

enum {
	VBE_DDC_EXT_GET_CAPS=0x00,
	VBE_DDC_EXT_GET_EDID=0x01,
};

typedef struct {
	uint8 ddcLevel;
	uint8 transferTime;
} PACKED vbe_ddc_caps_t;

typedef struct {
	uint8 header[8];
	uint8 manufacturerName[2];
	uint8 productName[2];
	uint32 serialNumber;
	uint8 manufacturerWeek;
	uint8 manufacturerYear;
	uint8 version;
	uint8 revision;
	uint8 videoInputDefinition;
	uint8 maxHorizontalImageSize;
	uint8 maxVerticalImageSize;
	uint8 displayTransferCharacteristic;
	uint8 featureSupport;
	uint8 redGreenLowBits;
	uint8 blueWhiteLowBits;
	uint8 redX;
	uint8 redY;
	uint8 greenX;
	uint8 greenY;
	uint8 blueX;
	uint8 blueY;
	uint8 whiteX;
	uint8 whiteY;
	uint8 establishedTimings1;
	uint8 establishedTimings2;
	uint8 manufacturerReservedTimings;
	uint16 standardTimingIdentification[8];
	uint8 detailedTimingDescription[72];
	uint8 extensionFlag;
	uint8 checksum;
} PACKED vbe_edid_t;

typedef struct {
	union {
		uint8 function;
		uint8 return_code;
	};
	
	union {
		vbe_controller_info_t info;
		
		vbe_modeinfo_t modeinfo;
		uint16 mode;
		
		vbe_set_mode_t setmode;
		vbe_get_mode_t getmode;
		
		vbe_set_display_start_t setstart;
		vbe_get_display_start_t getstart;
		
		vbe_ddc_ext_t ddcext;
		vbe_ddc_caps_t ddccaps;
		vbe_edid_t edid;
	};
} PACKED vbe_message_t;

#endif
